package source.view;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;

import source.controller.CustomKeyFileManager;
import source.controller.PlayerKeyListener;
import source.Driver;
import source.model.Position;
import source.model.type.*;
import source.view.viewobjects.*;

/**
 * The actual window that the end user will see.  This class will initialize
 * everything it needs and will make itself visible.
 * @author Steve
 *
 */
public class MainScreen extends JFrame {
	final public static int AREA_OVERVIEW = 0;
	final public static int UNIT_OVERVIEW = 1;
	final public static int STRUCTURE_OVERVIEW = 2;
	final public static int TECHNOLOGY_OVERVIEW = 3;
	
	private int currentPlayer;
	private static ConsoleViewport consoleViewport;
	private AreaOverview areaOverview;
	private StructureOverview structureOverview;
	private StatusViewport statusViewport;
	private TechnologyOverview techOverview;
	private JTabbedPane tabbedViewport;
	private UnitOverview unitOverview;
	private static MainScreen thisA;
	
	//MainScreen gets an array of PlayerKeyListeners so that it add and remove the key
	//listeners when a new turn comes	
	private PlayerKeyListener[] pkl;
	
	public MainScreen(PlayerKeyListener[] p, ViewData viewData){
		super("Main Screen");
		thisA = this;
		currentPlayer = 0;
		pkl = p;
		
		// Initialize the ImageLibrary
		ImageLibrary.init();
		
		// This is an elegant way to maximize the screen 
		setExtendedState(MAXIMIZED_BOTH);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		// This is a pretty sketchy way of making sure the gridbag work
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		dim.height = dim.height - 100;
		dim.width = dim.width - 30;
		
		//Initialize MainScreen's viewports
		consoleViewport = new ConsoleViewport();
		consoleViewport.setPreferredSize(new Dimension(dim.width * 3/4, dim.height /4));
		statusViewport = new StatusViewport(viewData);
		statusViewport.setPreferredSize(new Dimension(dim.width /4, dim.height));
		tabbedViewport = new JTabbedPane();
		tabbedViewport.setPreferredSize(new Dimension(dim.width * 3/4, dim.height *3/4));
		
		unitOverview = new UnitOverview(viewData, pkl[currentPlayer]);
		unitOverview.setPreferredSize(new Dimension(dim.width * 3/4, dim.height *3/4));
		
		structureOverview = new StructureOverview(viewData);
		structureOverview.setPreferredSize(new Dimension(dim.width * 3/4, dim.height *3/4));
		
		techOverview = new TechnologyOverview(viewData);
		techOverview.setPreferredSize(new Dimension(dim.width * 3/4, dim.height *3/4));
				
		//Initialize MainScreen's overviews
		// TODO: need may need to pass the map to the constructor
		ViewMap map = new ViewMap(Position.xBound, Position.yBound, viewData);
		areaOverview = new AreaOverview(map);
		areaOverview.setPreferredSize(new Dimension(dim.width * 3/4, dim.height *3/4));
		
		// Set up the tabbedViewport
		// TODO: Set up the tabbedViewport correctly
		tabbedViewport.add("Area", areaOverview);
		tabbedViewport.add("Units", unitOverview);
		tabbedViewport.add("Structures", structureOverview);
		tabbedViewport.add("Technology", techOverview);
		
		tabbedViewport.setTabPlacement(JTabbedPane.BOTTOM);
		
		// Set up the layout of our MainScreen
		Container pane = getContentPane();
		pane.setLayout(new GridBagLayout());
		
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.NONE;
		c.anchor = GridBagConstraints.PAGE_START;
		
		c.gridx = c.gridy = 0;
		c.gridheight = GridBagConstraints.REMAINDER;
		pane.add(statusViewport, c);
		
		c.gridx = 1;
		c.gridheight = 1;
		c.gridwidth = GridBagConstraints.REMAINDER;
		pane.add(tabbedViewport, c);
		
		c.gridx = 1;
		c.gridy = GridBagConstraints.RELATIVE;
		c.gridwidth = GridBagConstraints.REMAINDER;
		pane.add(consoleViewport,c);
		
		initMenuBar();
		//Add player 0's key and change listener before leaving constructor
		tabbedViewport.addChangeListener(pkl[0]);
		tabbedViewport.addChangeListener(pkl[1]);
	
	}

	/**
	 * Gives the overview focus in the tabbed pane.
	 * Valid Types:
	 * MainScreen.UNIT_OVERVIEW
	 * MainScreen.AREA_OVERVIEW
	 * MainScreen.STRUCTURE_OVERVIEW
	 * MainScreen.TECHNOLOGY_OVERVIEW
	 * 
	 * @param overview
	 */

	
	public void setOverview(int overview){
		switch(overview){
		case UNIT_OVERVIEW:
			tabbedViewport.setSelectedIndex(1);
			break;
		case AREA_OVERVIEW:
			tabbedViewport.setSelectedIndex(0);
			break;
		case STRUCTURE_OVERVIEW:
			tabbedViewport.setSelectedIndex(2);
			break;
		case TECHNOLOGY_OVERVIEW:
			tabbedViewport.setSelectedIndex(3);
			break;
		default:
			System.err.println("Tried to set tabbed panel to invalid overview");
		}
	}
	
	/**
	 * Writes str to the console followed by a carraige return.
	 * @param str String to print
	 * @param c Color
	 */
	public static void writeToConsole(String str, Color c){
		if(consoleViewport != null)
			consoleViewport.writeToConsole(str, c);
		else
			System.out.println(str);
	}
	/**
	 * Writes str to the console followed by a carrage return.
	 * @param str
	 */
	public static void writeToConsole(String str){
		writeToConsole(str, Color.BLACK);
	}
	
	/**
	 * Displays the keypad configuration dialog box.
	 */
	public void showKeypadConfigurationDialog(){
		//TODO: Change the Player Key Listener that is passed on.
		KeyMapDialog dialog = new KeyMapDialog(this , pkl[currentPlayer]);
		dialog.setVisible(true);
	}
	
	/**
	 * Prompts the user for the level type of the unit or structure that they want to build.
	 * @param buildType the type of entity that is being built.  For example Melee Unit.
	 * @param levels the build levels the user can choose from
	 * @return selected option
	 */
	public static String showBuildDialog(String buildType, String[] levels){
		String str = (String)JOptionPane.showInputDialog(thisA, "Build " + buildType + " Level:", "Build " + buildType, JOptionPane.PLAIN_MESSAGE, null, levels, levels[0]);
		return str;
	}
	
	/**
	 * Returns the View's Map.
	 * @return
	 */
	public ViewMap getMap(){
		return areaOverview.getMap();
	}
	
	public void updateScreens(){
		this.areaOverview.focusMap();
		this.statusViewport.update();
		
		if(tabbedViewport.getSelectedIndex() == 3){
			this.techOverview.update();
		}
	}
	
	public void updateOverviews(){
		this.unitOverview.update();
		this.structureOverview.update();
	}
	/**
	 * Sets up the menu bar for this MainScreen.
	 */
	private void initMenuBar(){
		JMenuBar menuBar = new JMenuBar();
		JMenu menu = new JMenu("Edit");
		JMenuItem item = new JMenuItem("Keyboard Configuration");
		item.setName("ConfigKeyboard");
		menu.add(item);
		menuBar.add(menu);
		
		item.addActionListener(new MainScreenMenuListener(this));
		setJMenuBar(menuBar);
	}
	
	/*public static void main(String[] args){
	
		
		 * Error was introducted when constructor for MainScreen was
		 * modified to take an array of PlayerKeyListeners
		 
		MainScreen frame = new MainScreen(null);
		frame.setVisible(true);
		
		try{
			Thread.sleep(1000);
			frame.setOverview(TECHNOLOGY_OVERVIEW);
			Thread.sleep(1000);
			frame.setOverview(UNIT_OVERVIEW);
			Thread.sleep(1000);
			frame.setOverview(STRUCTURE_OVERVIEW);
			Thread.sleep(1000);
			frame.setOverview(AREA_OVERVIEW);
			MainScreen.writeToConsole("hello Console");
		}
		catch(InterruptedException e){	}
	}*/
}
